//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.DirectoryServices;
using System.IO;
using System.Text.RegularExpressions;

using LitwareHR.Portfolio.Contract;
using LitwareHR.Portfolio.Services.Properties;

namespace LitwareHR.Portfolio.Services
{
    public class VirtualDirectoryManager
    {
        /// <summary>
        /// Type of virtual directory to be created.
        /// </summary>
        public enum VirtualDirectoryType
        {
            FTP,
            Web
        };

        public enum VirtualFolderType
        {
            FTP,
            Web
        };

        /// <summary>
        /// Creates the virual directory under the parent folder passed as a paramter
        /// </summary>
        static public void CreateVirtualDirectory(string iisServerAddress, string websiteId, string websitePhysicalPath, string virtualDirectoryName, VirtualDirectoryType directoryType, string parentFolder)
        {
            DirectoryEntry iisServerDE;
            DirectoryEntries websiteDE;
            DirectoryEntry virtualDirectory;

            try
            {
                //check whether to create FTP or Web IIS Virtual Directory
                if (directoryType == VirtualDirectoryType.Web)
                {
                    iisServerDE = new DirectoryEntry("IIS://" + iisServerAddress + "/W3SVC/" + websiteId + "/Root/" + parentFolder);
                }
                else
                {
                    iisServerDE = new DirectoryEntry("IIS://" + iisServerAddress + "/MSFTPSVC" + websiteId + "/Root/" + parentFolder);
                }
                //Get Default Web Site
                websiteDE = iisServerDE.Children;
                //Add row
                virtualDirectory = websiteDE.Add(virtualDirectoryName, iisServerDE.SchemaClassName.ToString());
                //Commit changes for Schema class File
                virtualDirectory.CommitChanges();
                if (!Directory.Exists(websitePhysicalPath))
                {
                    throw new DirectoryNotFoundException(Resources.VDirPhysicalPathFailed);
                }
                //Set virtual directory to physical path
                virtualDirectory.Properties["Path"].Value = websitePhysicalPath;
                //Set read access
                virtualDirectory.Properties["AccessRead"][0] = true;
                //Create Application for IIS Application (as for ASP.NET)
                if (directoryType == VirtualDirectoryType.Web)
                {
                    virtualDirectory.Invoke("AppCreate", true);
                    virtualDirectory.Properties["AppFriendlyName"][0] = virtualDirectoryName;
                    virtualDirectory.Properties["DefaultDoc"][0] = "default.htm,default.aspx,default.asp";
                }
                //Save all the changes
                virtualDirectory.CommitChanges();
                SwitchVirtualDirectoryAspNetVersion(virtualDirectory);
            }
            catch (System.Exception ex)
            {
                throw new ProvisioningException(Resources.VirtualDirectoryCreationFailed, ex);
            }
        }

        static public void CreateVirtualFolder(string iisServerAddress, string websiteId, string folderPhysicalPath, string virtualFolderName, VirtualFolderType folderType)
        {
            DirectoryEntry iisServerDE;
            DirectoryEntries websiteDE;
            DirectoryEntry virtualDirectory;
            try
            {
                //check whether to create FTP or Web IIS Virtual Directory
                if (folderType == VirtualFolderType.Web)
                {
                    iisServerDE = new DirectoryEntry("IIS://" + iisServerAddress + "/W3SVC/" + websiteId + "/Root");
                }
                else
                {
                    iisServerDE = new DirectoryEntry("IIS://" + iisServerAddress + "/MSFTPSVC/" + websiteId + "/Root");
                }

                //Get Default Web Site
                websiteDE = iisServerDE.Children;
                //Add row
                virtualDirectory = websiteDE.Add(virtualFolderName, iisServerDE.SchemaClassName.ToString());
                //Commit changes for Schema class File
                virtualDirectory.CommitChanges();
                if (!Directory.Exists(folderPhysicalPath))
                {
                    throw new DirectoryNotFoundException(Resources.VDirPhysicalPathFailed);
                }
                //Set virtual directory to physical path
                virtualDirectory.Properties["Path"].Value = folderPhysicalPath;
                //Set read access
                virtualDirectory.Properties["AccessRead"][0] = true;
                //Create Application for IIS Application (as for ASP.NET)
                if (folderType == VirtualFolderType.Web)
                {
                    virtualDirectory.Properties["AppFriendlyName"][0] = virtualFolderName;
                    virtualDirectory.Properties["DefaultDoc"][0] = "default.htm,default.aspx,default.asp";
                }
                //Save all the changes
                virtualDirectory.CommitChanges();
                SwitchVirtualDirectoryAspNetVersion(virtualDirectory);
            }
            catch (System.Exception ex)
            {
                throw new ProvisioningException(Resources.VirtualFolderCreationFailed, ex);
            }
        }

        static public void CreateVirtualFolder(string iisServerAddress, string websiteId, string folderPhysicalPath, string virtualFolderName, VirtualFolderType folderType, string parentVirtualDirectoryPath)
        {
            DirectoryEntry iisServerDE;
            DirectoryEntries websiteDE;
            DirectoryEntry virtualDirectory;
            try
            {
                //check whether to create FTP or Web IIS Virtual Directory
                if (folderType == VirtualFolderType.Web)
                {
                    iisServerDE = new DirectoryEntry("IIS://" + iisServerAddress + "/W3SVC/" + websiteId + "/Root/" + parentVirtualDirectoryPath);
                }
                else
                {
                    iisServerDE = new DirectoryEntry("IIS://" + iisServerAddress + "/MSFTPSVC/" + websiteId + "/Root/" + parentVirtualDirectoryPath);
                }
                
                //Get Default Web Site
                websiteDE = iisServerDE.Children;
                //Add row
                virtualDirectory = websiteDE.Add(virtualFolderName, iisServerDE.SchemaClassName.ToString());
                //Commit changes for Schema class File
                virtualDirectory.CommitChanges();
                if (!Directory.Exists(folderPhysicalPath))
                {
                    throw new DirectoryNotFoundException(Resources.VDirPhysicalPathFailed);
                }
                //Set virtual directory to physical path
                virtualDirectory.Properties["Path"].Value = folderPhysicalPath;
                //Set read access
                virtualDirectory.Properties["AccessRead"][0] = true;
                //Create Application for IIS Application (as for ASP.NET)
                if (folderType == VirtualFolderType.Web)
                {
                    virtualDirectory.Properties["AppFriendlyName"][0] = virtualFolderName;
                    virtualDirectory.Properties["DefaultDoc"][0] = "default.htm,default.aspx,default.asp";
                }
                //Save all the changes
                virtualDirectory.CommitChanges();
                SwitchVirtualDirectoryAspNetVersion(virtualDirectory);
            }
            catch (System.Exception ex)
            {
                throw new ProvisioningException(Resources.VirtualFolderCreationFailed, ex);
            }
        }

        private static void SwitchVirtualDirectoryAspNetVersion(DirectoryEntry virtualDirectory)
        {
            PropertyValueCollection scriptMapVals = virtualDirectory.Properties["ScriptMaps"];
            ArrayList objScriptMaps = new ArrayList();
            string frameworkVersion = "2.0.50727";
            Regex versionRegex = new Regex(@"(?<=\\v)\d{1}\.\d{1}\.\d{1,5}(?=\\)");
            //Assuming the version will always be something like n.n.nnnnn
            foreach (string scriptMapVal in scriptMapVals)
            {
                if (scriptMapVal.Contains("Framework"))
                {
                    objScriptMaps.Add(versionRegex.Replace(scriptMapVal, frameworkVersion));
                }
                else
                {
                    objScriptMaps.Add(scriptMapVal);
                }
            }
            virtualDirectory.Properties["ScriptMaps"].Value = objScriptMaps.ToArray();
            virtualDirectory.CommitChanges();
        }
    }
}